#include "tic_crow/tic_crow.h"

#include "handleJson/creatMap.hpp"
#include "yaml-cpp/yaml.h"
#include "handleJson/handleJson.hpp"
#include "handleJson/handleMap.hpp"
#include "handleJson/handleTask.hpp"
#include "handleJson/handlePoint.hpp"
#include "handleJson/handleVirtual.hpp"
#include "handleJson/handlePath.hpp"
#include "save_map/save_map.hpp"
#include "handleJson/creatTask.hpp"

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace json11;

void 
tic_crow::AppCrow::tic_crow(){
	//enter
	CROW_ROUTE(app,"/tic/order/enter")
	.methods("GET"_method)([&](const crow::request& req){

		Json ok = Json::object{	
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Success!"}
		};

		string MAP_PATH = "/root/TIC_MAP";
		vector<string> files = getFileName(MAP_PATH);
		
		if(files.size()==0){return crow::response(ok.dump());}
		
		string M_json_path = "/root/TIC_MAP/map.json";
		remove(M_json_path.c_str());

		for(int i=0;i<files.size();i++){
			
			ROS_INFO("write mapName:%s in map.json",files[i].c_str());
			Json map_info = getmapfile(files[i]);
			mapWrite(map_info);

			string T_json_path = "/root/TIC_MAP/" + files[i] +"/task.json";
			string P_json_path = "/root/TIC_MAP/" + files[i] +"/path.json";

			remove(T_json_path.c_str());

			Json Path_Json = ReadJson(P_json_path);
			Json::array Path_json_array = Path_Json["data"].array_items();
			if(Path_json_array.size()==0){
				continue;
			}

			for(int j=0;j<Path_json_array.size();j++){
				string path_name = Path_json_array[j]["name"].string_value();
				string path_type = Path_json_array[j]["type"].string_value();
				ROS_INFO("write taskName:%s in map.json",path_name.c_str());
				Json creat_task_json = getTaskJson(path_name,files[i],path_type);
				taskWrite(creat_task_json,T_json_path);
			}
		}
		return crow::response(ok.dump());
	});


	// add selected map_png
	CROW_ROUTE(app, "/tic/data/download_map")
	.methods("GET"_method)([&](const crow::request& req){
		Json error = Json::object{
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg","Failed to download the map, please try again!"}
		};

		const char* mapptr = req.url_params.get("map_name");
		if(!mapptr)
			return crow::response(400);
		string map_name = mapptr;
		cout<<map_name<<endl;
		Json map_info = getMapInfo(map_name);

		Json ok = Json::object{
			{"status", "OK"},
			{"data", map_info},
			{"msg", "Download map successfully"}
		};

		if(map_info.is_null()){
			return crow::response(error.dump());
		}
		return crow::response(ok.dump());
		
	});	

	CROW_ROUTE(app, "/tic/data/download_path")
	.methods("GET"_method)([&](const crow::request& req){
		
		Json error = Json::object{
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg","Failed to download the path, path is not exist!"}
		};
		const string map_name = req.url_params.get("map_name");
		const string path_name = req.url_params.get("path_name");
		
		// generate directory of map
		string path = "/root/TIC_MAP/" + map_name + "/path/" + path_name+".txt";
		ROS_INFO("path :%s",path.c_str());
		Json path_json = deal_path(path);
		if(path_json.is_null()){
			ROS_INFO("path_json is null");
			return crow::response(error.dump());
		}

		Json ok = Json::object{
			{"status", "OK"},
			{"data", path_json},
			{"msg", "Download path successfully"}
		};
		// path_txt = ReadJson(path);
		return crow::response(ok.dump());
	});	

	// get all_list
	CROW_ROUTE(app, "/tic/data/data_list")
	.methods("GET"_method)([&](const crow::request& req){
		Json ok = Json::object{
        	{"status", "OK"},
        	{"data",Json::array{}},
        	{"msg", "The status is gotten successfully"}
    	};

		Json error = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to get the status, please try again!"}
    	};

		string map_json_path ="/root/TIC_MAP/map.json";

    	if( access(map_json_path.c_str(),F_OK)!=0){
			ROS_INFO("%s is not exist",map_json_path.c_str());
			return crow::response(ok.dump());
		}
		
		Json map_list = ReadJson(map_json_path);
    	Json::array map_array = map_list["data"].array_items();
    	Json::object object_;
    	Json::array map_info;
    	for(int i = 0;i<=map_array.size()-1;i++){     	
        	string map_name = map_array[i]["mapFileName"].string_value();
			cout<<"map_name:"<<map_name<<endl;
			string map_path = "/root/TIC_MAP/"+map_name;

       	 	object_ = handleMapJsonToApp(map_array[i].object_items());

			string task_path = map_path+"/task.json";
			Json task_list = ReadJson(task_path);
			Json::array task_array = task_list["data"].array_items();

			string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";
			Json group_task_list = ReadJson(group_task_path);
			Json::array group_task_array = group_task_list["data"].array_items();

			if(task_array.size()>0){
				if(group_task_array.size()>0){
					for(int x = 0;x<group_task_array.size();x++){
						Json::object group_task_object = group_task_array[x].object_items();
						task_array.push_back(group_task_object);
					}
				}
				Json::object task_object;
				Json::array task_info;
				for(int j = 0;j<task_array.size();j++){
					task_object = handleTaskJsonToApp(task_array[j].object_items());
					Json task_list(task_object);
					task_info.push_back(task_list);
				}
				
				object_["tasks"] = task_info;
			}else{
				object_["tasks"] = Json::object{};
			}
			string point_path = map_path+"/point.json";
			Json point_list = ReadJson(point_path);
        	Json::array point_array = point_list["data"].array_items(); 
        	object_["points"] = point_array;

        	Json map_list_(object_);

        	map_info.push_back(map_list_);      
    	}
    	ok = Json::object{
        	{"status", "OK"},
        	{"data",map_info},
        	{"msg", "The status is gotten successfully"}
    	};
		return crow::response(ok.dump());
	});

	// control robot
	CROW_ROUTE(app, "/tic/order/shift")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{	
			{"status", "OK"},
			{"data",Json::object{}},
			{"msg", ""}
		};

		string body = req.body;
		string err;
		Json speed = Json::parse(body,err);
		double linearspeed = speed["speed"]["linearSpeed"].number_value();
		double angularspeed = speed["speed"]["angularSpeed"].number_value();
		
		geometry_msgs::Twist vel;
		vel.linear.x = linearspeed*4;
		vel.angular.z = angularspeed*3;
		vel_pub.publish(vel);
		
		return crow::response(ok.dump());
		
	});

	// start to scan map
	CROW_ROUTE(app, "/tic/order/start_scan_map")
	.methods("POST"_method)([&](const crow::request& req){
	
		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", ""}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to start scanning the map, Please try again"}
		};
		points.clear();
		const char* PID_ = "slam_gmapping";
		if(ProcessIsRun(PID_)){
			system("sh /root/tic_run/script/mapping.sh &");	
			map_flag_ = "NULL";		
			return crow::response(ok.dump());
	
		}else{
			return crow::response(error.dump());
		}

	});

	// mapping
	CROW_ROUTE(app, "/tic/data/mapping")
	.methods("POST"_method)([&](const crow::request& req){
		auto time = std::chrono::system_clock::now();
		cout<<time.time_since_epoch().count()<<endl;
		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed "}
		};
		string mapname = "/root/TIC_MAP/temp.pgm";
		string png_path = "/root/TIC_MAP/temp.png";
		MapSaver mg(mapname,png_path);

		while(!mg.saved_map_ && ros::ok()){
			ros::spinOnce();
		}

		get_robot_pose g_pose;
		while(!g_pose.finish_handle && ros::ok()){
			ros::spinOnce();
		}
		poseinfo point_info;
		point_info.poseX = g_pose.x;
		point_info.poseY = g_pose.y;
		point_info.height = mg.height;
		point_info.weight = mg.width;
		point_info.originX = mg.originX;
		point_info.originY = mg.originY;
		cout<<"point_info.poseX:"<<point_info.poseX<<"		point_info.poseY:"<<point_info.poseX<<endl;

		Denoising(png_path,point_info);
		Json png_json = base64_pgm(png_path);
		string png_string = png_json["data"].string_value();
		Json data = Json::object{
			{"data", png_string},
			{"height", mg.height},
			{"width", mg.width},
			{"originX",mg.originX},
			{"originY",mg.originY},
			{"resolution",mg.resolution}
		};
		Json ok = Json::object{
			{"status", "OK"},
			{"data", data},
			{"msg", "success"}
		};

		if(png_json.is_null()){
			return crow::response(error.dump());
		}else{
			auto time_ = std::chrono::system_clock::now();
			cout<<time_.time_since_epoch().count()<<endl;
			return crow::response(ok.dump());
		}

	});
	// end up scanning map
	CROW_ROUTE(app, "/tic/order/finish_scan_map")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok0 = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Unsave map successfully"}
		};

		Json ok1 = Json::object{	
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Save map successfully"}
		};

		Json error0 = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "map is exist!"}
		};

		Json error1 = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to save the map, please try again!"}
		};

		const char* actionptr = req.url_params.get("action");
		const char* mapptr = req.url_params.get("map_name");
		if(!(actionptr && mapptr))
			return crow::response(400);
		
		int action = atoi(actionptr);
		string map_name = mapptr;
		string path = "/root/TIC_MAP/";
		string map_path = "/root/TIC_MAP/"+map_name;
		string map_path_path = map_path+"/path";
		const char* PID_ = "slam_gampping";
		string map_json = "/root/TIC_MAP/map.json";
		string mapname = map_path+"/"+map_name;
		string png_path = "/root/TIC_MAP/"+map_name+"/"+map_name+".png";
		
		if(action == 0){
			//stop scanning map
			system("rosnode kill /slam_gmapping &");
			ROS_INFO("Unsave map");
			return crow::response(ok0.dump());
		}

		if(action == 1){
			if( access(path.c_str(),F_OK)!=0){
        		ROS_INFO("%s does not exist!!!",path.c_str());
        		if(mkdir(path.c_str(),0)!=0){
					ROS_INFO("%s mkdir error",path.c_str());
					return crow::response(error1.dump());
				}
    		}
			if( access(map_path.c_str(),F_OK)!=0){
        		ROS_INFO("%s does not exist!!!",map_path.c_str());
        		if(mkdir(map_path.c_str(),0)!=0){
					ROS_INFO("%s mkdir error",map_path.c_str());
					return crow::response(error1.dump());
				}
				if(mkdir(map_path_path.c_str(),0)!=0){
					ROS_INFO("%s mkdir error",map_path_path.c_str());
					return crow::response(error1.dump());
				}
    		}

			int threshold_occupied = 65;
			int threshold_free = 25;
			MapGenerator mg(mapname, threshold_occupied, threshold_free);

			while(!mg.saved_map_ && ros::ok()){
				ros::spinOnce();
			}
			get_robot_pose g_pose;
			while(!g_pose.finish_handle && ros::ok()){
				ros::spinOnce();
			}
			poseinfo point_info;
			point_info.poseX = g_pose.x;
			point_info.poseY = g_pose.y;
			point_info.height = mg.height;
			point_info.weight = mg.width;
			point_info.originX = mg.originX;
			point_info.originY = mg.originY;

			Denoising(png_path,point_info);
			int status;
			status = system("rosnode kill /slam_gmapping");;
			if(status<0){
				printf("error : %s",strerror(errno));
				return crow::response(error1.dump());
			}
			if(WIFEXITED(status)){
				printf("normal termination,exit status = %d\n",WIFEXITED(status));//取得ticcmd执行结果

				Json map_info = creatmap(map_name);
				mapWrite(map_info);
				return crow::response(ok1.dump());
			}else if(WIFSIGNALED(status)){
				printf("abnormal termination,signal number = %d\n",WIFSIGNALED(status));//如果cmd被信号中断取得信号值
			}else if(WIFSTOPPED(status)){
				printf("process stopped ,signal number = %d\n",WIFSTOPPED(status));//如果cmd被暂停执行，取得信号值
			}
			return crow::response(error1.dump());
		}
	});
	
	// launch server_ map
	CROW_ROUTE(app, "/tic/order/server_map")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Launch the map successfully"}
		};

		Json error0 = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "The map do not exist, please check your map name or rescan a new map!"}
		};

		Json error1 = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to launch the map, please try again"}
		};

		const char* mapptr = req.url_params.get("map_name");
		
		if(!mapptr){
			return crow::response(400);
		}

		string map_name = mapptr;
		string map_path = "/root/TIC_MAP/"+map_name;
		ROS_INFO("map_path : %s",map_path.c_str());
		cout<<map_flag_<<"  "<<map_name<<endl;
		
		if(access(map_path.c_str(),F_OK)==0){
			
			if (map_flag_.compare(map_name)) {
				char ticCMD[256];
				ROS_INFO("launch mapServer: %s",map_name.c_str());
				sprintf(ticCMD, "sh /root/tic_run/script/mapServer.sh %s &", map_name.c_str());

				int status;
				status = system(ticCMD);
				if(status<0){
					printf("error : %s",strerror(errno));
					return crow::response(error1.dump());
				}
				if(WIFEXITED(status)){
					printf("normal termination,exit status = %d\n",WIFEXITED(status));//取得ticcmd执行结果
					map_flag_ = map_name;
					return crow::response(ok.dump());
				}else if(WIFSIGNALED(status)){
					printf("abnormal termination,signal number = %d\n",WIFSIGNALED(status));//如果cmd被信号中断取得信号值
				}else if(WIFSTOPPED(status)){
					printf("process stopped ,signal number = %d\n",WIFSTOPPED(status));//如果cmd被暂停执行，取得信号值
				}

				return crow::response(error1.dump());
			}
			else{
				ROS_INFO("mapServer: %s has launched",map_name.c_str());
				return crow::response(ok.dump());
			}
		}else
			return crow::response(error0.dump());
	});

	CROW_ROUTE(app, "/tic/order/rename_map")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Modify the map name successfully"}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to modify the map name, new mapname is exist or you want mod map is not exist!"}
		};

		const char* mapptr = req.url_params.get("map_name");
		const char* new_mapptr = req.url_params.get("new_map_name");
		ROS_INFO("old name: %s, new name: %s\n", mapptr, new_mapptr);

		if(!(mapptr && new_mapptr))
			return crow::response(400);

		string map_name_t = mapptr;
		string new_map_name_t = new_mapptr;
		string old_name_folder = "/root/TIC_MAP/" + map_name_t;
		string new_name_folder = "/root/TIC_MAP/" + new_map_name_t;
		string old_name_yaml = new_name_folder + "/" + map_name_t + ".yaml";
		string old_name_pgm = new_name_folder + "/" + map_name_t + ".pgm";
		string new_name_yaml = new_name_folder + "/" + new_map_name_t + ".yaml";
		string new_name_pgm = new_name_folder + "/" + new_map_name_t + ".pgm";

		string old_name_png = new_name_folder + "/" + map_name_t + ".png";
		string new_name_png = new_name_folder + "/" + new_map_name_t + ".png";
		// modify map_name
		if(access(new_name_folder.c_str(),F_OK)!=0 && access(old_name_folder.c_str(),F_OK)==0){
			
			RenameFile(old_name_folder.c_str(), new_name_folder.c_str());
			RenameFile(old_name_yaml.c_str(), new_name_yaml.c_str()); 
			RenameFile(old_name_pgm.c_str(), new_name_pgm.c_str());
			RenameFile(old_name_png.c_str(), new_name_png.c_str());
		
			//mod yaml
			YAML::Node config = YAML::LoadFile(new_name_yaml);
			cout << "image :"<<config["image"].as<string>()<<endl;
			ofstream fout(new_name_yaml);

			config["image"] = new_name_png;

			fout << config;

			fout.close();
			cout << "image :"<<config["image"].as<string>()<<endl;

			//mod map.json
			mapEdit(map_name_t,new_map_name_t);

			string point_path = "/root/TIC_MAP/"+new_map_name_t+"/point.json";
			pointMapEdit(new_map_name_t,point_path);

			string task_path = "/root/TIC_MAP/"+new_map_name_t+"/task.json";
			taskMapEdit(new_map_name_t,task_path);

			string group_task_path = "/root/TIC_MAP/"+new_map_name_t+"/group_task.json";
			taskMapEdit(new_map_name_t,group_task_path);

			return crow::response(ok.dump());
		}
			
		else
			return crow::response(error.dump());
	});


	// delete maps
	CROW_ROUTE(app, "/tic/order/delete_map")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Delete the map successfully"}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to delete the map, please try again!"}
		};

		//github.com/ipkn/crow
		const char* mapptr = req.url_params.get("map_name");
		if(!mapptr)
			return crow::response(400);

		string map_name = mapptr;
		string map_path = "/root/TIC_MAP/"+map_name;
		
		if(mapDelete(map_name) == 0 && DeleteFile(map_path.c_str()) == 0){
			ROS_INFO("mapDelete(%s), DeleteFile(%s)",map_name.c_str(), map_path.c_str());
			return crow::response(ok.dump());
		}
		else
			return crow::response(error.dump());
	});

	//initial point
	CROW_ROUTE(app, "/tic/order/pose/initialPoint")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{		
			{"status", "OK"},
			{"data",Json::object{}},
			{"msg","Initialize successfully"}
		};

		Json error = Json::object{		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to initialize, please try again!"}
		};
	
		string point = req.body;
		string err;
		Json initialPoint = Json::parse(point, err);
		// cout<<initialPoint.dump()<<endl;

		float angle = initialPoint["angle"].number_value();
		float gridX = initialPoint["gridX"].number_value();
		float gridY = initialPoint["gridY"].number_value();
		string pointName = initialPoint["name"].string_value();
		string pointType = initialPoint["type"].string_value();

		ROS_INFO("angle:%f,gridX:%f,gridY:%f",angle,gridX,gridY);
		tf::Quaternion q;
		q.setRPY(0, 0, angle);

		geometry_msgs::PoseWithCovarianceStamped msg_poseinit;
		msg_poseinit.header.frame_id = "map";
		msg_poseinit.header.stamp = ros::Time::now();
		msg_poseinit.pose.pose.position.x = gridX;
		msg_poseinit.pose.pose.position.y = gridY;
		msg_poseinit.pose.pose.position.z = 0;
		msg_poseinit.pose.pose.orientation.x = 0.0;
		msg_poseinit.pose.pose.orientation.y = 0.0;
		msg_poseinit.pose.pose.orientation.z = q[2];
		msg_poseinit.pose.pose.orientation.w = q[3];

		for(int i = 0; i < 32; i++){
			msg_poseinit.pose.covariance[i] = 0;
		}

		msg_poseinit.pose.covariance[0] = 0.25;
		msg_poseinit.pose.covariance[7] = 0.25;
		msg_poseinit.pose.covariance[31] =0.06853891945200942; 
		
		initialpose_pub.publish(msg_poseinit);
        
		movemotor_presisecontrol::StartRotate StartRotate;
		StartRotate.request.angle = 360.0;
		StartRotate.request.speed = 0.3;

		movemotor_presisecontrol::CheckRotate CheckRotate;		

		// check rotate_client call value is true or false?
		if(Rotate_client.call(StartRotate)){
			ROS_INFO("Rotate_client call scuessful");
			while(ros::ok()){
				if(checkRotate_client.call(CheckRotate)){
					if(CheckRotate.response.isFinished)break;
				}else{
					ROS_INFO("checkRotate_client.call fail!!!");
					return crow::response(error.dump());
				}
			}
			return crow::response(ok.dump());
		}else{
			ROS_INFO("Rotate_client call error");
			return crow::response(error.dump());
		}

	});

	//add navigation point
	// no need to implement the function temporarily
	CROW_ROUTE(app, "/tic/order/pose/add_pose")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Add navigatepoint successfully!"}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to add navigatepoint successfully!"}
		};

		string s_point = req.body;
		string err;
		//TODO: add navigation point
		Json point = Json::parse(s_point, err);
		cout<<point.dump()<<endl;
		string mapName = point["mapName"].string_value();
		string point_path = "/root/TIC_MAP/"+mapName+"/"+"point.json";
		
		int flag = pointWrite(point,point_path);

		if(flag == 0)
			return crow::response(ok.dump());
		else
			return crow::response(error.dump());
	
	});

	//delete point
	CROW_ROUTE(app, "/tic/order/pose/delete_pose")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Delete navigatepoint successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to delete navigatepoint successfully!"}
		};
		string map_name = req.url_params.get("map_name");
		string pose_name = req.url_params.get("pose_name");

		string map_path = "/root/TIC_MAP/"+map_name+"/"+"point.json";
		
		int flag = pointDelete(pose_name,map_path);

		if(flag == 0)
			return crow::response(ok.dump());
		else
			return crow::response(error.dump());
	});
	
	// start to record the path
	CROW_ROUTE(app, "/tic/order/path_record_start")
	.methods("POST"_method)([&](const crow::request& req){

		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Start to record the path successfully!"}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to record the path, please try again!"}
		};

		string map_name = req.url_params.get("map_name");
		string path_name = req.url_params.get("path_name");
		string filepath = "/root/TIC_MAP/" + map_name + "/path/" + path_name + ".txt";
		
		char ticCMD[256];
		sprintf(ticCMD, "roslaunch pathplanner pathrecord.launch filepath:=%s  &", filepath.c_str());
		system(ticCMD);
		//TODO: figure out the PID of MyPath to judge response 
		const char* PID_ = "pathrecord";
		if(!ProcessIsRun(PID_))
			return crow::response(ok.dump());		
		else
			return crow::response(error.dump());

	});

	//save or unsave the path record
	CROW_ROUTE(app, "/tic/order/path_record_finish")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok0 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Unsave path_name successfully"}
		};
		Json ok1 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Save path_name successfully"}
		};
		Json error0 = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to unsave the path_name, please try again!"}
		};
		Json error1 = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to save the path_name, please try again!"}
		};
		string map_name = req.url_params.get("map_name");
		string path_name = req.url_params.get("path_name");
		char* c_action = req.url_params.get("action");
		int action = atoi(c_action);

		string filepath = "/root/TIC_MAP/" + map_name + "/path/" + path_name + ".txt";

		std_msgs::String end_pathrecord;
		end_pathrecord.data = "Finish";
		
		if(action == 0){
			ROS_INFO("Finish record dont save");
			//unsave the path_name
			finish_pathrecord.publish(end_pathrecord);
			
			if(DeleteFile(filepath.c_str())){
				system("kill -9 $(pidof pathrecord) &");
				return crow::response(ok0.dump());
			}else{
				return crow::response(error0.dump());
			}
		}
		if(action == 1){
			ROS_INFO("Finish record save");
			//save the path_name
			finish_pathrecord.publish(end_pathrecord);

			while(ros::ok()){
				if(access(filepath.c_str(),F_OK)==0 && monitor_file(filepath.c_str()))
					break;
			}

			if(access(filepath.c_str(),0)!=0){
				//start to record the path
				cout << "The file you expected does not exist!!!" << endl;
			
				return crow::response(error1.dump());
			}
			else{
				ROS_INFO("writing teach path.json");
				creatPathTask p_task(path_name,"teach");
				Json p_json = p_task.creatPathJson();
				string P_json_path = "/root/TIC_MAP/" + map_name +"/path.json";
				pathWrite(p_json,P_json_path);
				return crow::response(ok1.dump());
			}
		}
	});


	// region coverage
	CROW_ROUTE(app, "/tic/order/add_area_path")
	.methods("POST"_method)([&](const crow::request& req){
		
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to add area_path, please try again!"}
		};

		string s_area = req.body;
		string err;
		Json area = Json::parse(s_area, err);
		string mapName = area["mapName"].string_value();
		string path_type = area["path_type"].string_value();
		string pathName = area["pathName"].string_value()+".txt";
		Json::array array_area = area["area"].array_items();

		stringstream area_point_name;
		double x,y;
		for(int i = 0;i<array_area.size();i++){
			
			x = array_area[i]["x"].number_value();
			y = array_area[i]["y"].number_value();
			area_point_name<<x<<","<<y<<" ";
		}

		char ticCMD[1024];
		sprintf(ticCMD, "roslaunch ipa_room_exploration room_exploration_client.launch map_name:=%s task_name:=%s click_point:=\"%s\" ",
																		mapName.c_str(), pathName.c_str(),area_point_name.str().c_str());

		int status;
		status = system(ticCMD);
		if(status<0){
			printf("error : %s",strerror(errno));
			return crow::response(error.dump());
		}
		if(WIFEXITED(status)){
			printf("normal termination,exit status = %d\n",WIFEXITED(status));//取得ticcmd执行结果
		}else if(WIFSIGNALED(status)){
			printf("abnormal termination,signal number = %d\n",WIFSIGNALED(status));//如果cmd被信号中断取得信号值
		}else if(WIFSTOPPED(status)){
			printf("process stopped ,signal number = %d\n",WIFSTOPPED(status));//如果cmd被暂停执行，取得信号值
		}

		
		string path = "/root/TIC_MAP/" + mapName + "/path/" + pathName;

		if( access(path.c_str(),F_OK)!=0){
        	cout << "The file :"<<path<<"you expected does not exist!!!" << endl;
        	return crow::response(error.dump());
		}
		ROS_INFO("creat area path success");
		Json path_json = deal_path(path);
		if(path_json.is_null()){return crow::response(error.dump());}

		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", path_json},
			{"msg", "Add area_path successfully!"}
		};
		ROS_INFO("writing area path.json");
		creatPathTask p_task(area["pathName"].string_value(),"area");
		Json p_json = p_task.creatPathJson();
		string P_json_path = "/root/TIC_MAP/" + mapName +"/path.json";
		pathWrite(p_json,P_json_path);
		return crow::response(ok.dump());
	});

	// add multiple tasks
	CROW_ROUTE(app, "/tic/order/add_task")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Add tasks successfully!"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to add tasks, please try again!"}
		};
		string s_task = req.body;
		string err;
		Json task = Json::parse(s_task, err);
		cout<<task.dump()<<endl;
		// string task_name = task["task_name"].string_value();
		string map_name = task["map_name"].string_value();
		string task_path = "/root/TIC_MAP/"+map_name+"/"+"task.json";
		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";
		Json::array task_path_array = task["use_path"].array_items();
		if(task_path_array.size()==1){
			int flag = taskWrite(task,task_path);
			if(flag == 0)
				return crow::response(ok.dump());
			else
				return crow::response(error.dump());
		}else{
			int flag = taskWrite(task,group_task_path);
			if(flag == 0)
				return crow::response(ok.dump());
			else
				return crow::response(error.dump());
		}
	});

	// edit task
	CROW_ROUTE(app, "/tic/order/edit_task")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Edit the task successfully!"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to edit the task, please try again!"}
		};
		string s_task = req.body;
		string err;
		Json task = Json::parse(s_task, err);
		// cout<<task.dump()<<endl;
		// string task_name = task["task_name"].string_value();
		string map_name = task["map_name"].string_value();
		int task_brushLevel = task["use_path"][0]["motor_level"]["brushLevel"].int_value();
		int task_brushLift = task["use_path"][0]["motor_level"]["brushLift"].int_value();
		int task_waterSpray = task["use_path"][0]["motor_level"]["waterSpray"].int_value();
		int task_wiperLift = task["use_path"][0]["motor_level"]["wiperLift"].int_value();
		int task_vacuum = task["use_path"][0]["motor_level"]["vacuum"].int_value();
		int task_shakeLevel = task["use_path"][0]["motor_level"]["shakeLevel"].int_value();

		ROS_INFO("brushLevel:%d,brushLift:%d,waterSpray:%d,wiperLift:%d,vacuum:%d,shakeLevel:%d",
			task_brushLevel,task_brushLift,task_waterSpray,task_wiperLift,task_vacuum,task_shakeLevel);

		srv.request.config.ints.at(brush_level).value = task_brushLevel;
		srv.request.config.ints.at(brush_lift).value = task_brushLift;
		srv.request.config.ints.at(water_spray).value = task_waterSpray;
		srv.request.config.ints.at(wiper_lift).value = task_wiperLift;
		srv.request.config.ints.at(vacuum_level).value = task_vacuum;
		srv.request.config.ints.at(shake_level).value = task_shakeLevel;

		// ROS_INFO("brushLevel:%d,brushLift:%d,waterSpray:%d,wiperLift:%d,vacuum:%d,shakeLevel:%d",
		// 	srv.request.config.ints.at(brush_level).value,
		// 	srv.request.config.ints.at(brush_lift).value,
		// 	srv.request.config.ints.at(water_spray).value,
		// 	srv.request.config.ints.at(wiper_lift).value,
		// 	srv.request.config.ints.at(vacuum_level).value,
		// 	srv.request.config.ints.at(shake_level).value);
    	parameters_client.call(srv);

		//get "use_path"
		string task_path = "/root/TIC_MAP/"+map_name+"/"+"task.json";
		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";
		Json::array task_path_array = task["use_path"].array_items();
		if(task_path_array.size()==1){
		//edit task
			int flag = taskEdit(task,task_path);
			if(flag == 0){
				
				return crow::response(ok.dump());
			}	
			else
				return crow::response(error.dump());
		}else{
			int flag = taskEdit(task,group_task_path);
			if(flag == 0){
				
				return crow::response(ok.dump());
			}	
			else
				return crow::response(error.dump());
		}
	});
	
	// delete task
	CROW_ROUTE(app, "/tic/order/delete_task")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Delete the task successfully!"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to delete the task, please try again!"}
		};
		string map_name = req.url_params.get("map_name");
		string task_name = req.url_params.get("task_name");

		string task_path = "/root/TIC_MAP/"+map_name+"/"+"task.json";
		string path_path = "/root/TIC_MAP/"+map_name+"/"+"path.json";
		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";

		Json task_json = ReadJson(task_path);
		Json::array task_json_data = task_json["data"].array_items();
		int exist_flag = judgeNameInTaskJson(task_name,task_json_data);
		//delete task
		if(exist_flag==1){
			int flag = taskdelete(task_name,task_path);

			if(flag == 0){
				string p_path = "/root/TIC_MAP/"+map_name+"/path/"+task_name+".txt";
				remove(p_path.c_str());
				pathDelete(task_name,path_path);
				ROS_INFO("Delete task successfully!");			
				return crow::response(ok.dump());
			}	
			else
				return crow::response(error.dump());
		}else{
			int flag = taskdelete(task_name,group_task_path);

			if(flag == 0){
				ROS_INFO("Delete task successfully!");			
				return crow::response(ok.dump());
			}	
			else
				return crow::response(error.dump());
		}
	});

	// task rename
	CROW_ROUTE(app, "/tic/order/rename_task")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Rename the task successfully!"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to rename the task, please try again!"}
		};

		string map_name = req.url_params.get("map_name");
		string task_name = req.url_params.get("task_name");
		string new_task_name = req.url_params.get("new_task_name");

		string taskJson_path = "/root/TIC_MAP/"+map_name+"/task.json";
		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";
		string path_path = "/root/TIC_MAP/"+map_name+"/path.json";

		Json task_json = ReadJson(taskJson_path);
		Json::array task_json_data = task_json["data"].array_items();
		int exist_flag = judgeNameInTaskJson(task_name,task_json_data);

		if(exist_flag==1){
			int flag = taskRename(task_name,new_task_name,taskJson_path);

			string old_path_name = "/root/TIC_MAP/"+map_name+"/path/"+task_name+".txt";
			string new_path_name = "/root/TIC_MAP/"+map_name+"/path/"+new_task_name+".txt";
			//task rename
			if(flag == 0){
				RenameFile(old_path_name.c_str(),new_path_name.c_str());
				pathEdit(task_name,new_task_name,path_path);
				return crow::response(ok.dump());
			}
			else
				return crow::response(error.dump());
		}else{
			int flag = taskRename(task_name,new_task_name,group_task_path);
			if(flag == 0){
				return crow::response(ok.dump());
			}
			else
				return crow::response(error.dump());

		}
	});

	// excute task
	CROW_ROUTE(app, "/tic/order/start_task")
	.methods("POST"_method)([](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Start the task successfully!"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to start the task, path no exist!"}
		};

		string s_task = req.body;
		string err;
		Json start_task = Json::parse(s_task, err);
		
		string task_name = start_task["task_name"].string_value();
		string map_name = start_task["map_name"].string_value();
		int loop_times = start_task["loop_times"].int_value();

		string path_name = "/root/TIC_MAP/" + map_name + "/task.json";
		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";

		Json task_json = ReadJson(path_name);
		Json::array task_json_data = task_json["data"].array_items();
		int exist_flag = judgeNameInTaskJson(task_name,task_json_data);

		if(exist_flag==1){
			//TODO: excute task	
			if(!access(path_name.c_str(),0)){
				char ticCMD[1024];
				sprintf(ticCMD, "roslaunch pathplanner pathplay.launch filepath:=%s  cycle:=%d task_name:=%s exec_last_task:=false &", 
																					path_name.c_str(), loop_times, task_name.c_str());
				system(ticCMD);
				return crow::response(ok.dump());
			}
			else{
				ROS_INFO("path_name:%sis not exist",path_name.c_str());
				return crow::response(error.dump());
			}
				
		}else{
			if(!access(group_task_path.c_str(),0)){
				char ticCMD[1024];
				sprintf(ticCMD, "roslaunch pathplanner pathplay.launch filepath:=%s  cycle:=%d task_name:=%s exec_last_task:=false &", 
																					group_task_path.c_str(), loop_times, task_name.c_str());
				system(ticCMD);
				return crow::response(ok.dump());
			}
			else{
				ROS_INFO("group_task_path:%sis not exist",group_task_path.c_str());
				return crow::response(error.dump());
			}
		}

		
	});

	CROW_ROUTE(app, "/tic/order/continue_task")
	.methods("POST"_method)([](const crow::request& req){
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to continue the task, path no exist!"}
		};

		string s_task = req.body;
		string err;
		Json continue_task = Json::parse(s_task, err);
		
		string task_name = continue_task["task_name"].string_value();
		string map_name = continue_task["map_name"].string_value();
		
		string path_name = "/root/TIC_MAP/" + map_name + "/task.json";
		ROS_INFO("path_name:%s",path_name.c_str());

		string group_task_path = "/root/TIC_MAP/"+map_name+"/"+"group_task.json";

		Json task_json = ReadJson(path_name);
		Json::array task_json_data = task_json["data"].array_items();
		int exist_flag = judgeNameInTaskJson(task_name,task_json_data);

		if(exist_flag==1){
			// //TODO: excute task	
			if(!access(path_name.c_str(),0)){
				char ticCMD[1024];
				sprintf(ticCMD, "roslaunch pathplanner pathplay.launch filepath:=%s cycle:=0 task_name:=%s exec_last_task:=true &", 
																	path_name.c_str(), task_name.c_str());
				system(ticCMD);
				// handle_task_status get_loop_times;
				// while(!get_loop_times.finish_handle && ros::ok()){
				// 	ros::spinOnce();
				// }
				//int loop_times = get_loop_times.taskAllCount-get_loop_times.taskCount;
				int loop_times = 2;
				ROS_INFO("loop_times:%d",loop_times);
				Json ok = Json::object{
			
					{"status", "OK"},
					{"data", Json::object{{"loop_times",loop_times}}},
					{"msg", "Start the task successfully!"}
				};
				return crow::response(ok.dump());
			}
			else
				return crow::response(error.dump());
		}else{
			// //TODO: excute task	
			if(!access(group_task_path.c_str(),0)){
				char ticCMD[1024];
				sprintf(ticCMD, "roslaunch pathplanner pathplay.launch filepath:=%s cycle:=0 task_name:=%s exec_last_task:=true &", 
																	group_task_path.c_str(), task_name.c_str());
				system(ticCMD);
				// handle_task_status get_loop_times;
				// while(!get_loop_times.finish_handle && ros::ok()){
				// 	ros::spinOnce();
				// }
				//int loop_times = get_loop_times.taskAllCount-get_loop_times.taskCount;
				int loop_times = 2;
				ROS_INFO("loop_times:%d",loop_times);
				Json ok = Json::object{
			
					{"status", "OK"},
					{"data", Json::object{{"loop_times",loop_times}}},
					{"msg", "Start the task successfully!"}
				};
				return crow::response(ok.dump());
			}
			else
				return crow::response(error.dump());
		}
		
		
	});

	//pause or restore task
	CROW_ROUTE(app, "/tic/order/pause_task")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok0 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "The task was paused successfully"}
		};
		Json ok1 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "The task was restored successfully"}
		};
		Json error0 = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to pause the task, please try again!"}
		};
		Json error1 = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to restore the task, please try again!"}
		};
		const char* c_action = req.url_params.get("action");
		if(!c_action)
			return crow::response(400);

		int action = atoi(c_action);

		if(action == 0){
			
			//pause the task
			std_msgs::Bool pause_task;
			pause_task.data = false;
			pub_task.publish(pause_task);
			return crow::response(ok0.dump());
		}
		if(action == 1){
		
			//TODO: restore the task
			std_msgs::Bool pause_task;
			pause_task.data = true;
			pub_task.publish(pause_task);
			return crow::response(ok1.dump());
		}
		return crow::response(error0.dump());
	});

	// stop the task
	CROW_ROUTE(app, "/tic/order/stop_task")
	.methods("POST"_method)([&](const crow::request& req){

		Json ok = Json::object{
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "The task was stoped successfully"}
		};

		Json error = Json::object{
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to stop the task, please try again!"}
		};

		std_msgs::Bool stop_task_msg;
		stop_task_msg.data = true;
		stop_task.publish(stop_task_msg);
		return crow::response(ok.dump());
	});

	// send device_manager info
	CROW_ROUTE(app, "/tic/data/device_manager")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "The device_manager is sent successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to send the device_manager, please try again!"}
		};
	
		string s_device = req.body;
		string err;
		Json device_manager = Json::parse(s_device, err);
		if(device_manager.is_null()){return crow::response(error.dump());}
		ROS_INFO("brushLevel:%d,brushLift:%d,waterSpray:%d,wiperLift:%d,vacuum:%d,shakeLevel:%d",
				device_manager["brushLevel"].int_value(),
				device_manager["brushLift"].int_value(),
				device_manager["waterSpray"].int_value(),
				device_manager["wiperLift"].int_value(),
				device_manager["vacuum"].int_value(),
				device_manager["shakeLevel"].int_value());
		msg.values.at(brush_level).value = std::to_string(device_manager["brushLevel"].int_value());
		msg.values.at(brush_lift).value = std::to_string(device_manager["brushLift"].int_value());
		msg.values.at(water_spray).value = std::to_string(device_manager["waterSpray"].int_value());
		msg.values.at(wiper_lift).value = std::to_string(device_manager["wiperLift"].int_value());
		msg.values.at(vacuum_level).value = std::to_string(device_manager["vacuum"].int_value());
		msg.values.at(shake_level).value = std::to_string(device_manager["shakeLevel"].int_value());

    	boardcmdPub.publish(msg);
		return crow::response(ok.dump());
	});


	// add virtual wall
	CROW_ROUTE(app, "/tic/order/add_virtual_wall")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg","Add virtual wall successfully"}
		};
		Json error = Json::object{
		
			{"status", "error"},
			{"data", Json::object{}},
			{"msg","The map.pgm is not exist"}
		};

		string map_wall = req.body;
		string err;
		Json virWall = Json::parse(map_wall, err);

		string mapName = virWall["mapName"].string_value();
		string path = "/root/TIC_MAP/"+mapName+"/"+mapName+".pgm";

		string json_path = "/root/TIC_MAP/"+mapName+"/"+"virtual.json";
		string save_png_path = "/root/TIC_MAP/"+mapName+"/"+mapName+".png";

		int flag = virtualWrite(virWall,json_path);
		if(flag != 0) return crow::response(error.dump());

		int flag_ = line_virtual(path,json_path,save_png_path);
		if(flag_ != 0) return crow::response(error.dump());

		char ticCMD[256];
		sprintf(ticCMD, "sh /root/tic_run/script/mapServer.sh %s &", mapName.c_str());
		system(ticCMD);

		return crow::response(ok.dump());
	});

	//Mark non-sweepable areas
	CROW_ROUTE(app, "/tic/order/add_virtual_area")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Add virtual area successfully"}
		};

		Json error = Json::object{
		
			{"status", "error"},
			{"data", Json::object{}},
			{"msg","The map.pgm is not exist"}
		};

		string map_area = req.body;
		string err;
		Json virarea = Json::parse(map_area,err);
		// cout<<virarea.dump()<<endl;
		string mapName = virarea["mapName"].string_value();

		string path = "/root/TIC_MAP/"+mapName+"/"+mapName+".pgm";
		string save_png_path = "/root/TIC_MAP/"+mapName+"/"+mapName+".png";

		string json_path = "/root/TIC_MAP/"+mapName+"/"+"virtual.json";

		int flag = virtualWrite(virarea,json_path);
		if(flag != 0) return crow::response(error.dump());

		int flag_ = line_virtual(path,json_path,save_png_path);
		if(flag_ != 0) return crow::response(error.dump());

		char ticCMD[256];
		sprintf(ticCMD, "sh /root/tic_run/script/mapServer.sh %s &", mapName.c_str());
		system(ticCMD);
		
		return crow::response(ok.dump());
	
	});
	
	//delete_virtual_wall
	CROW_ROUTE(app, "/tic/order/delete_virtual_wall")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok1 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg","Delete virtual wall successfully"}
		};
		Json ok2 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg","Restore virtual wall successfully"}
		};
		Json error = Json::object{
		
			{"status", "error"},
			{"data", Json::object{}},
			{"msg","The map.pgm is not exist"}
		};
		string map_wall = req.body;
		string err;
		Json virWall = Json::parse(map_wall, err);

		string mapName = virWall["mapName"].string_value();
		string path = "/root/TIC_MAP/"+mapName+"/"+mapName+".pgm";

		string json_path = "/root/TIC_MAP/"+mapName+"/"+"virtual.json";
		string save_png_path = "/root/TIC_MAP/"+mapName+"/"+mapName+".png";

		char* c_action = req.url_params.get("action");
		if(!c_action)
			return crow::response(400);

		int action = atoi(c_action);
		if(action == 0){
			
			int flag = virtualDelete(virWall,json_path);
			if(flag != 0) return crow::response(error.dump());
			line_virtual(path,json_path,save_png_path);

			char ticCMD[256];
			sprintf(ticCMD, "sh /root/tic_run/script/mapServer.sh %s &", mapName.c_str());
			system(ticCMD);

			return crow::response(ok1.dump());
		}
		if(action == 1){
			int flag = virtualDeleteWall(json_path);
			if(flag != 0) return crow::response(error.dump());
			return crow::response(ok2.dump());
		}
	});

	//delete_virtual_area
	CROW_ROUTE(app, "/tic/order/delete_virtual_area")
	.methods("POST"_method)([&](const crow::request& req){
		Json ok1 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg","Delete virtual area successfully"}
		};
		Json ok2 = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg","Restore virtual area successfully"}
		};
		Json error = Json::object{
		
			{"status", "error"},
			{"data", Json::object{}},
			{"msg","The map.pgm is not exist"}
		};
		string map_area = req.body;
		string err;
		Json virarea = Json::parse(map_area,err);
		// cout<<virarea.dump()<<endl;
		string mapName = virarea["mapName"].string_value();
		string path = "/root/TIC_MAP/"+mapName+"/"+mapName+".pgm";

		string json_path = "/root/TIC_MAP/"+mapName+"/"+"virtual.json";
		string save_png_path = "/root/TIC_MAP/"+mapName+"/"+mapName+".png";
		char* c_action = req.url_params.get("action");
		if(!c_action)
			return crow::response(400);

		int action = atoi(c_action);
		if(action == 0){
			int flag = virtualDelete(virarea,json_path);
			if(flag != 0) return crow::response(error.dump());
			line_virtual(path,json_path,save_png_path);

			char ticCMD[256];
			sprintf(ticCMD, "sh /root/tic_run/script/mapServer.sh %s &", mapName.c_str());
			system(ticCMD);
			
			return crow::response(ok1.dump());
		}
		if(action == 1){
			int flag = virtualDeleteArea(json_path);
			if(flag != 0) return crow::response(error.dump());
			return crow::response(ok2.dump());
		}
	
	});
	// send work_status info
	CROW_ROUTE(app, "/tic/real_data/work_status")
	.methods("GET"_method)([](){
	
		// how to get real_data
		Json data = Json::object{
		
			{"task_name", "tic_task"}
		};

		Json ok = Json::object{
		
			{"status","OK"},
			{"data",data},
			{"msg", "The work_status is gotten successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to get the work_status"}
		};

		if(0)
			return crow::response(error.dump());
		else
			return crow::response(ok.dump());
	
	});

	// send device_status info
	CROW_ROUTE(app, "/tic/data/device_status")
	.methods("GET"_method)([](){
	
		Json data = Json::object{
		
			{"batttery",100}
		};

		
		Json ok = Json::object{
		
			{"status","OK"},
			{"data",data},
			{"msg", "The device_status is gotten successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data",Json::object{}},
			{"msg", "Failed to get the device_status"}
		};

		if(0)
			return crow::response(error.dump());
		else
			return crow::response(ok.dump());
	
	
	});
	

	//rebot_check
	CROW_ROUTE(app, "/tic/order/robot_check")
	.methods("GET"_method)([](){
	
		Json Data = Json::object{
		
			{"level",0},
			{"name", "SensorStatus"}
		};
		
		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Data},
			{"msg", "The robot_check info is gotten successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to get the robot_check info, please try again"}
		};
	
		if(0)
			return crow::response(error.dump());
		else
			return crow::response(ok.dump());
	});

	//shut_down check
	CROW_ROUTE(app, "/tic/order/shut_down")
	.methods("GET"_method)([](){
	
		//TODO:implement "shut_dow check" function

		Json ok = Json::object{
		
			{"status", "OK"},
			{"data", Json::object{}},
			{"msg", "Shut down successfully"}
		};
		Json error = Json::object{
		
			{"status", "Error"},
			{"data", Json::object{}},
			{"msg", "Failed to shut_down"}
		};
		
		if(0)
			return crow::response(error.dump());
		else
			return crow::response(ok.dump());

	});

	// try to find url and param
	CROW_ROUTE(app,"/cmd/setAction")
	.methods("GET"_method)([](const crow::request& req){

		const char* actInf = req.url_params.get("direction");
		if(*actInf == 'w'){

			return crow::response("forward");
		}
		else return crow::response("unknow");

	});

	CROW_ROUTE(app,"/cmd/setPose")
	.methods("GET"_method)([](const crow::request& req){
	
		// virtual wall param intro: first bit is point number,rest part, per eight bit is a point 
		char *ppoint = req.url_params.get("virtualwall");
		if(ppoint == NULL){
		
			return crow::response("NO found virtual wall param\n");
		}
		int point_num = atoi(ppoint);
		stringstream temp;
		temp << point_num;
		return crow::response(temp.str());
	});


	app.port(5000).multithreaded().run();
	ROS_INFO("shutting down!");
    ros::shutdown();
    }
